﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using AlipaySDK.Dto;
using AlipaySDK.Dto.Auth;
using Aop.Api;
using Aop.Api.Request;
using Aop.Api.Response;
using Aop.Api.Util;

namespace AlipaySDK.Helper
{
    public class Auth
    {

        /// <summary>
        /// 得到accesstoken
        /// </summary>
        /// <param name="authCode">Alipay auth_code</param>
        /// <param name="appId">服务窗appid</param>
        /// <returns></returns>
        public static GetOauth2OpenIdResponse GetOauth2OpenId(string authCode, string appId)
        {
            const string grantType = "authorization_code";
            AlipaySystemOauthTokenRequest accesstokenRequst = new AlipaySystemOauthTokenRequest();
            accesstokenRequst.Code = authCode;
            accesstokenRequst.GrantType = grantType;

            IAopClient client = new DefaultAopClient(AopConfig.serverUrl, appId, AopConfig.merchant_private_key);
            AlipaySystemOauthTokenResponse accesstokenResponse = client.Execute(accesstokenRequst);
            if (accesstokenResponse != null && accesstokenResponse.AlipayUserId != null &&
                accesstokenResponse.AlipayUserId != "")
            {
                string accessToken = accesstokenResponse.AccessToken;
                string openid = accesstokenResponse.AlipayUserId;
                return new GetOauth2OpenIdResponse()
                {
                    ResultCode = "0",
                    ResultMsg = "",
                    OpenId = openid,
                    AccessToken = accessToken
                };
            }
            else
            {
                return new GetOauth2OpenIdResponse()
                {
                    ResultCode = "1",
                    ResultMsg = ""
                };
            }
        }

        /// <summary>
        /// 网页授权流程中,第三步通过auth_token换取用户信息
        /// </summary>
        /// <param name="appId"></param>
        /// <param name="authToken"></param>
        /// <returns></returns>
        public static GetOauth2UserInfoResponse GetOauth2UserinfoShare(string appId,string authToken)
        {
            AlipayUserUserinfoShareRequest userinfoRequst = new AlipayUserUserinfoShareRequest();
            IAopClient client = new DefaultAopClient(AopConfig.serverUrl, appId, AopConfig.merchant_private_key);
            AlipayUserUserinfoShareResponse userinfoResponse = client.Execute(userinfoRequst, authToken);
            if (!string.IsNullOrEmpty(userinfoResponse.CertNo)  && !string.IsNullOrEmpty(userinfoResponse.CertTypeValue)
                && !string.IsNullOrEmpty(userinfoResponse.Gender) && !string.IsNullOrEmpty(userinfoResponse.Mobile )
                && !string.IsNullOrEmpty(userinfoResponse.RealName) )
            {
                return new GetOauth2UserInfoResponse()
                {
                    ResultCode = "0",
                    ResultMsg = "",
                    CertNo = userinfoResponse.CertNo,
                    CertTypeValue = userinfoResponse.CertTypeValue,// 0
                    Gender = userinfoResponse.Gender.ToLower() == "m" ? "男" : "女", //m   f
                    Mobile = userinfoResponse.Mobile,
                    RealName = userinfoResponse.RealName
                };
            }
            else
            {
                return new GetOauth2UserInfoResponse()
                {
                    ResultCode = "1",
                    ResultMsg = ""
                };
            }
        }

        /// <summary>
        /// 创建二维码
        /// </summary>
        /// <param name="request">二维码请求<see cref="CreateQrCodeResultRequest"/></param>
        /// <param name="appId">服务窗id</param>
        /// <returns></returns>
        public static CreateQrCodeResultResponse CreateQrCodeResult(CreateQrCodeResultRequest request,string appId)
        {
            AlipayMobilePublicQrcodeCreateRequest createQrRequst = new AlipayMobilePublicQrcodeCreateRequest();
            createQrRequst.BizContent = Newtonsoft.Json.JsonConvert.SerializeObject(request);
            Dictionary<string, string> paramsDict = (Dictionary<string, string>)createQrRequst.GetParameters();
            IAopClient client = new DefaultAopClient(AopConfig.serverUrl, appId, AopConfig.merchant_private_key);
            AlipayMobilePublicQrcodeCreateResponse createQrCodeResponse = client.Execute(createQrRequst);

            if (createQrCodeResponse != null && createQrCodeResponse.Code == "200")
            {
                return new CreateQrCodeResultResponse
                {
                    ResultCode = "0",
                    ResultMsg = "",
                    CodeImg = createQrCodeResponse.CodeImg,
                    ExpireSecond = createQrCodeResponse.ExpireSecond.ToString()
                };
            }
            else
            {
                return new CreateQrCodeResultResponse
                {
                    ResultCode = "1",
                    ResultMsg = createQrCodeResponse == null ? "" : createQrCodeResponse.Msg,
                    CodeImg = "",
                    ExpireSecond = ""
                };
            }

        }
        /// <summary>
        /// 绑定就诊卡
        /// </summary>
        /// <param name="request">添加帐号请求<see cref="AddAccountRequest"/></param>
        /// <returns></returns>
        public static BaseResponse AddAccount(AddAccountRequest request)
        {

            AlipayMobilePublicAccountAddRequest accountAddRequst = new AlipayMobilePublicAccountAddRequest();
            accountAddRequst.BizContent = Newtonsoft.Json.JsonConvert.SerializeObject(request);
            Dictionary<string, string> paramsDict = (Dictionary<string, string>)accountAddRequst.GetParameters();
            IAopClient client = new DefaultAopClient(AopConfig.serverUrl, request.appId, AopConfig.merchant_private_key);
            AlipayMobilePublicAccountAddResponse accountAddResponse = client.Execute(accountAddRequst);

            if (accountAddResponse != null && accountAddResponse.Code == "200")
            {
                return new BaseResponse
                {
                    ResultCode = "0",
                    ResultMsg = ""
                };
            }
            else
            {
                return new BaseResponse
                {
                    ResultCode = "1",
                    ResultMsg = accountAddResponse == null ? "" : accountAddResponse.Msg
                };
            }

        }

        /// <summary>
        /// 解绑就诊卡
        /// </summary>
        /// <param name="request">解绑就卡请求</param>
        /// <returns></returns>
        public static BaseResponse DeleteAccount(DeleteAccountRequest request)
        {

            AlipayMobilePublicAccountDeleteRequest accountDeleteRequst = new AlipayMobilePublicAccountDeleteRequest();
            request.appId = request.appId;
            accountDeleteRequst.BizContent = Newtonsoft.Json.JsonConvert.SerializeObject(request);
            Dictionary<string, string> paramsDict = (Dictionary<string, string>)accountDeleteRequst.GetParameters();
            IAopClient client = new DefaultAopClient(AopConfig.serverUrl, request.appId, AopConfig.merchant_private_key);
            AlipayMobilePublicAccountDeleteResponse accountDeleteResponse = client.Execute(accountDeleteRequst);

            if (accountDeleteResponse != null && accountDeleteResponse.Code == "200")
            {
                return new BaseResponse
                {
                    ResultCode = "0",
                    ResultMsg = ""
                };
            }
            else
            {
                return new BaseResponse
                {
                    ResultCode = "1",
                    ResultMsg = accountDeleteResponse == null ? "" : accountDeleteResponse.Msg
                };
            }

        }

        /// <summary>
        /// 验签支付宝请求
        /// </summary>
        /// <param name="param"></param>
        /// <returns></returns>
        public static bool VerifySignAlipayRequest(Dictionary<string, string> param)
        {
            bool result = Aop.Api.Util.AlipaySignature.RSACheckV2(param, AopConfig.alipay_public_key, "GBK");
            return result;
        }

        /// <summary>
        /// 支付宝验证商户网关
        /// </summary>
        public static string Verifygw(Dictionary<string, string> dict, out bool isValid)
        {
            isValid = false;
            string rtnstr = "";

            string bizContent = dict["biz_content"];
            if (!VerifySignAlipayRequest(dict))
            {
                rtnstr = VerifygwResponse(false, AopConfig.getMerchantPublicKeyStr());
                isValid = false;
            }
            XmlDocument xmlDoc = new XmlDocument();
            xmlDoc.LoadXml(bizContent);
            string eventType = xmlDoc.SelectSingleNode("//EventType")?.InnerText??"";
            if ("verifygw".Equals(eventType))
            {
                rtnstr = VerifygwResponse(true, AopConfig.getMerchantPublicKeyStr());
                isValid = true;
            }
            return rtnstr;
        }


        ///// <summary>/// 遍历Url中的参数列表/// </summary>
        ///// <returns>如:(?userName=keleyi&userType=1)</returns>
        //public static string GetUrlParam(Dictionary<string, string> param)
        //{
        //    string urlParam = "";
        //    if (param != null)
        //    {
        //        urlParam = param.Keys.Aggregate(urlParam, (current, key) => current + (key + "=" + param[key] + "&"));
        //        urlParam = urlParam.Substring(0, urlParam.LastIndexOf('&'));
        //    }
        //    return urlParam;
        //}

        /// <summary>
        /// 验证网关，签名内容并返回给支付宝xml
        /// </summary>
        /// <param name="result">true或false</param>
        /// <param name="merchantPubKey"></param>
        /// <returns></returns>
        public static string VerifygwResponse(bool result, string merchantPubKey)
        {
            XmlDocument xmlDoc = new XmlDocument(); //创建实例
            XmlDeclaration xmldecl = xmlDoc.CreateXmlDeclaration("1.0", "GBK", null);
            xmlDoc.AppendChild(xmldecl);
            XmlElement xmlElem = xmlDoc.CreateElement("alipay"); //新建元素

            XmlElement response = xmlDoc.CreateElement("response");
            XmlElement success = xmlDoc.CreateElement("success");
            if (result)
            {
                success.InnerText = "true"; //设置文本节点 
                response.AppendChild(success); //添加到<Node>节点中 
            }
            else
            {
                success.InnerText = "false"; //设置文本节点 
                response.AppendChild(success); //添加到<Node>节点中 
                XmlElement err = xmlDoc.CreateElement("error_code");
                err.InnerText = "VERIFY_FAILED";
                response.AppendChild(err);
            }
            XmlElement bizContent = xmlDoc.CreateElement("biz_content");
            bizContent.InnerText = merchantPubKey;
            response.AppendChild(bizContent);
            xmlElem.AppendChild(response);
            string _sign = AlipaySignature.RSASign(response.InnerXml, AopConfig.merchant_private_key, AopConfig.charset);
            XmlElement sign = xmlDoc.CreateElement("sign");
            sign.InnerText = _sign;
            xmlElem.AppendChild(sign);
            XmlElement signType = xmlDoc.CreateElement("sign_type");
            signType.InnerText = "RSA";
            xmlElem.AppendChild(signType);

            xmlDoc.AppendChild(xmlElem); //添加元素

            return xmlDoc.InnerXml;

        }
    }
}
